<template>
  <Row>
    <Col ref="wrapRef" v-bind="formCol">
      <ProForm
        class="px-4"
        labelAlign="right"
        ref="formRef"
        :items="_items"
        :formColLayout="colSpan"
        :model="model"
        :labelCol="{ span: 7 }"
        :wrapperCol="{ span: 20 }"
        :onValuesChange="changeFormState"
      ></ProForm>
    </Col>
    <Col v-bind="btnCol">
      <Flex justify="end">
        <Space>
          <Button icon="search" @click="() => onSearch()">
            {{ searchText }}
          </Button>
          <Button icon="reset" @click="() => onReset()"> 重置 </Button>
        </Space>
      </Flex>
      <Flex justify="end" class="mt-[24px]">
        <div v-if="hideExpand" @click="isExpand = !isExpand">
          <AButton v-if="isExpand" class="px-[10px]">
            <div class="flex items-center">
              <SvgIcon class="w-3 h-3 mr-1" name="collapse" />
              <span>收起</span>
            </div>
          </AButton>
          <AButton v-else class="px-[10px]">
            <div class="flex items-center">
              <SvgIcon class="w-3 h-3 mr-1" name="expend" />
              <span>展开</span>
            </div>
          </AButton>
        </div>
      </Flex>
    </Col>
  </Row>
</template>

<script setup lang="tsx">
import { PropType, computed, ref, watch } from 'vue';
import { useElementSize } from '@vueuse/core';
import {
  Button as AButton,
  Col,
  Flex,
  Grid,
  Row,
  Space,
  TableColumnType,
} from 'ant-design-vue';
import { ProForm, type ProFormProps } from '@/components/ProForm/index';
import SvgIcon from '@/components/SvgIcons/Index.vue';
import Button from '../../../Button/index';

defineOptions({
  name: 'SearchForm',
});

const emit = defineEmits<{
  search: [Record<string, any>];
  change: [Record<string, any>, Record<string, any>];
  reset: [Record<string, any>];
}>();

const props = defineProps({
  items: {
    type: Array as PropType<TableColumnType[]>,
    default: () => [],
  },
  formCol: {
    type: Object,
    required: true,
  },
  btnCol: {
    type: Object,
    required: true,
  },
  searchText: {
    type: String,
    default: '搜索',
  },
});
const _model: Record<string, any> = {};

for (const item of props.items) {
  if (item.defaultValue) {
    _model[item.dataIndex as string] = item.defaultValue;
  }
}

const model = ref(_model);

const formRef = ref();
const onSearch = async (params?: Record<string, any>) => {
  if (params) {
    for (const key in params) {
      if (Object.prototype.hasOwnProperty.call(params, key)) {
        formRef.value.setFiledValue(key, params[key]);
      }
    }
  }
  const formState = await formRef.value.validate();
  emitSearch(formState);
};

const onReset = () => {
  for (const item of props.items) {
    formRef.value.setFiledValue(item.dataIndex, item.defaultValue);
  }
  const formState = formRef.value.getFieldsValue();
  emitSearch(formState);
  emit('reset', formState);
};

const emitSearch = (formState: any) => {
  emit('search', formState);
};

const changeFormState = (changeValues: any, formState: any) => {
  emit('change', changeValues, formState);
};
const isExpand = ref(false);

const formItems = computed<Exclude<ProFormProps['items'], undefined>>(() => {
  const result = props.items
    .sort((a, b) => {
      return (a?.order || Infinity) - (b.order || Infinity);
    })
    .reduce<Exclude<ProFormProps['items'], undefined>>((prev, cur) => {
      if (!cur.hideInSearch) {
        const params: Partial<
          Exclude<ProFormProps['items'], undefined>[number]
        > = {
          label: cur.title as string,
          field: (cur.dataIndex || cur.key) as string,
        };
        if (cur.valueEnum !== undefined) {
          const options = Object.keys(cur.valueEnum).map((key) => {
            return {
              label: cur.valueEnum![key],
              value: key,
            };
          });
          params.type = 'select';
          params.props = {
            options,
            placeholder: '请选择',
            allowClear: !cur.hideClear,
          };
        } else if (cur.isTime) {
          params.type = 'dateRange';
          params.props = {};
        } else if (cur.customSearchRender) {
          params.customRender = cur.customSearchRender;
        } else {
          (params.type = 'input'),
            (params.props = {
              placeholder: '请输入',
              allowClear: true,
            });
        }
        prev.push({
          ...params,
          order: cur.order,
        } as Exclude<ProFormProps['items'], undefined>[number]);
      }
      return prev;
    }, []);
  return result;
});

const hideExpand = ref(false);

const wrapRef = ref();
const { width } = useElementSize(wrapRef);
console.log(width, 'width');
const num = computed(() => {
  return width.value > 1100
    ? 4
    : width.value > 900
      ? 3
      : width.value > 600
        ? 2
        : 1;
});
const colSpan = computed(() => {
  return {
    span: 24 / num.value,
  };
});

const _items = computed(() => {
  if (formItems.value.length === 0) {
    return [];
  }

  hideExpand.value = num.value < formItems.value.length / 2;

  const items = isExpand.value
    ? formItems.value
    : formItems.value.slice(0, num.value * 2);

  return [...items] as Exclude<ProFormProps['items'], undefined>;
});

defineExpose({
  reset() {
    onReset();
  },
  search(params?: Record<string, any>) {
    onSearch(params);
  },
});
</script>
